﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
namespace Manager.Compress
{
    [Serializable]
   public class CompressFiles
   {

       #region Header

        bool FileCompressed = false;
       string magic;
       string FileName = String.Empty;
       string fileVersion = "1.0";
       UInt32 numFiles;
       DateTime timestamp;

       #endregion

       #region Stream

      //FileStream inFile = null;
       FileStream outFile = null;
       MemoryStream mStream = null;
       GZipStream Compress = null;
       byte[] chunkBytes;

       #endregion

       public string pFileName
       {
           get
           {
                             return FileName;
           }

           set
           {

               FileName = value;

           }

       }

       public CompressFiles()
       {

           if (FileCompressed == true)
           {

               FileName = "test1_compressed.cbs";


           }
           else
           {

               FileName = "test1_semcompressao.cbs";

           }

           mStream = new MemoryStream();
           chunkBytes = new byte[mStream.Length];
           Compress = new GZipStream(mStream, CompressionMode.Compress,true);
           outFile = new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite);


           timestamp = DateTime.Now.ToLocalTime();
           magic = generateMagicToken();



       }

       public CompressFiles(bool isCompressed)
       {

           FileCompressed = isCompressed;
           mStream = new MemoryStream();
           chunkBytes = new byte[mStream.Length];
           Compress = new GZipStream(mStream, CompressionMode.Compress, true);
           outFile = new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite);
           timestamp = DateTime.Now.ToLocalTime();
           magic = generateMagicToken();


       }
      
       public void AddHeader()
       {
           FileCompressed = false;
           BinaryFormatter bf = new BinaryFormatter();
           bf.Serialize(mStream, numFiles);
           bf.Serialize(mStream, FileName);
           bf.Serialize(mStream, fileVersion);
           bf.Serialize(mStream, timestamp);
           bf.Serialize(mStream, magic);
          
          

       }


       public int PutFiles(List<Bitmap> listBitmap)
       {
           BinaryFormatter bf = new BinaryFormatter();
           int i;
           for (i = 0; i < listBitmap.Count; i++)
           {
               if (FileCompressed == true)
               {
                   bf.Serialize(mStream, listBitmap[i]);
               }
               else
               {

                   listBitmap[i].Save(mStream, System.Drawing.Imaging.ImageFormat.Bmp);
                   chunkBytes = mStream.ToArray();
               }
             // Compress.Write(chunkBytes, mStream.ToArray().Length, mStream.ToArray().Length * 1024);

               numFiles++;
           }

          

           return i; ;
         


       }

       public void saveFileStrings(List<string> strList)
       {
           BinaryFormatter bf = new BinaryFormatter();
           for (int i = 0; i < strList.Count; i++)
           {
              bf.Serialize(mStream, strList[i].ToString());
           }


       }


       public void WriteToFile(List<Bitmap> bmp)
       {


           PutFiles(bmp);

           mStream.Seek(0, SeekOrigin.Begin);
           AddHeader();
           mStream.WriteTo(outFile);
           outFile.Flush();
           outFile.Close();

          


       }

       public void WriteToFile(List<Bitmap> bmp, List<string> namefiles, string path, bool isCompressed)
       {


           if (isCompressed == true)
           {
               chunkBytes = mStream.ToArray();
               PutFiles(bmp);
               saveFileStrings(namefiles);
               //Compress.Seek(0, SeekOrigin.Begin);
               AddHeader();
               // Compress.Write(chunkBytes, chunkBytes.Length, mStream.ToArray().Length);
               //outFile.Read(chunkBytes,0, 1024);
               mStream.WriteTo(outFile);
      
           }
           else
           {


               PutFiles(bmp);
               saveFileStrings(namefiles);
               mStream.Seek(0, SeekOrigin.Begin);
               AddHeader();
               FileName = path;
               mStream.WriteTo(outFile);
               // Compress.Write(chunkBytes, 0, mStream;);
           }

           outFile.Flush();
           outFile.Close();

       }



       private string generateMagicToken()
       {
           StringBuilder strBuilder = new StringBuilder();
           Random rnd = new Random();

           char tab;
           for (int i = 0; i <= 32; i++)
           {
               
               tab = Convert.ToChar(Convert.ToInt32( Math.Floor(i + rnd.NextDouble())));
               strBuilder.Append(tab);
           }

           return strBuilder.ToString();
       }




   }
}
